package org.pizza.rocket.core.producer;

import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionChecker;
import org.pizza.rocket.core.annotation.RocketTransactionListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.StandardEnvironment;

import java.util.Map;
import java.util.Properties;

/**
 * @author 高巍
 * email kynb_club@163.com
 * @since 2020/11/24 1:32 下午
 */
@Slf4j
public class TransactionProducerRegister implements ApplicationContextAware, SmartInitializingSingleton {
    private ConfigurableApplicationContext applicationContext;
    private final StandardEnvironment environment;
    private final RocketMQProducer rocketMQProducer;

    public TransactionProducerRegister(StandardEnvironment environment, RocketMQProducer rocketMQProducer) {
        this.environment = environment;
        this.rocketMQProducer = rocketMQProducer;
    }

    @Override
    public void afterSingletonsInstantiated() {
        Map<String, Object> beans = this.applicationContext.getBeansWithAnnotation(RocketTransactionListener.class);
        beans.forEach(this::registerTransactionProducer);
    }

    private void registerTransactionProducer(String beanName, Object bean) {
        Class<?> clazz = AopProxyUtils.ultimateTargetClass(bean);
        RocketTransactionListener annotation = clazz.getAnnotation(RocketTransactionListener.class);
        if (LocalTransactionChecker.class.isAssignableFrom(bean.getClass())) {
            Properties properties = new Properties();
            properties.setProperty(PropertyKeyConst.AccessKey, environment.resolvePlaceholders(annotation.accessKey()));
            properties.setProperty(PropertyKeyConst.SecretKey, environment.resolvePlaceholders(annotation.secretKey()));
            properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, environment.resolvePlaceholders(annotation.nameServer()));
            rocketMQProducer.createAndStartTransactionProducer(annotation.producerGroup(), (LocalTransactionChecker) bean, properties);
            if (log.isInfoEnabled()) {
                log.info("producerGroup:{} create and Start TransactionProducer success", annotation.producerGroup());
            }
        }
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    }
}
